<template>
	<view class="container">
		<view style="width: 100%;">
			<custom title="生成九宫格图片"></custom>
		</view>
		<view style="height: 10px;"></view>
		<view class="imgs-list" :class="{ loading: !imageParts.length }" @click="chooseImage">
			<view class="imgs-list-bg" v-if="imgsListBg"
				:style="{ background: `url(${imgsListBg}) left top / 100% 100% no-repeat` }"></view>
			<image v-for="(part, index) in imageParts" :key="index" class="imgs-list-item" :src="part.data"
				mode="aspectFill" @click.stop="saveSingleImage(index)"
				:style="part.data?'':'background-color:#f7f7f7;'" />
			<view v-if="!imageParts.length" class="placeholder-text">☞点我选择图片☜</view>
		</view>
		<!-- :style="{width:previewBoxWidth +'px',height:previewBoxHeight+'px'}" -->
		<view class="preview-box" v-if="previewSrc" @touchmove="touchMove" @touchend="touchEnd" @mousemove="touchMove"
			@mouseup="touchEnd" @mousedown="startMove">
			<image @load="imageLoad" class="preview" :src="previewSrc" mode="widthFix" :style="previewStyle" />
			<view class="kuangkuang" :style="kuangkuangStyle"></view>
		</view>

		<!-- #ifdef H5 -->
		<view class="desc-text" v-if="imageParts.length">
			点击或者长按单张图片可下载/保存
			<!-- <text class="edit-width" @click="editWidth">修改间隙</text> -->
		</view>
		<!-- #endif -->

		<view class="button-group">
			<view class="choose-btn hover-o" @click="chooseImage">选择图片</view>
			<view class="save-btn hover-o" @click="saveAllImages" v-if="imageParts.length">保存图片</view>
		</view>

		<view style="height: 0;">
			<canvas id="canvas1" canvas-id="canvas1"
				:style="{width:canvasWidth+'px',height:canvasHeight+'px'}"></canvas>
		</view>

	</view>
</template>

<script>
	// import { saveAs } from 'file-saver';
	// import JSZip from 'jszip';

	export default {
		data() {
			return {
				cha: 0,
				leftCha: 0,
				topCha: 0,
				aspectRatio: 1,
				imageParts: [],

				storeWidth: 4,
				previewSrc: '',
				imgsListBg: '',
				lastTouchX: null,
				lastTouchY: null,
				marginTop: 0,
				marginLeft: 0,
				isStartMove: false,
				canvasWidth: 1000,
				canvasHeight: 1000,

				previewBoxWidth: 80,
				previewBoxHeight: 80,
			};
		},
		computed: {
			previewStyle() {
				let style = {
					opacity: 0.8
				};

				if (this.aspectRatio > 1) {
					style.width = `${80 * this.aspectRatio}px`;
					style.height = '80px';
				} else {
					style.width = '80px';
					style.height = `${80 / this.aspectRatio}px`;
				}

				return style;
			},
			kuangkuangStyle() {
				return {
					marginTop: `${this.marginTop}px`,
					marginLeft: `${this.marginLeft}px`
				};
			}
		},
		created() {
			this.file = null;
		},
		methods: {
			imageLoad(e) {

				this.file.width = e.detail.width;
				this.file.height = e.detail.height;
				let img = this.file;
				const minWidth = Math.min(img.width, img.height, 1500);
				this.aspectRatio = img.width / img.height;



				const ctx = uni.createCanvasContext('canvas1', this);

				let drawWidth = minWidth;
				let drawHeight = minWidth / this.aspectRatio;

				if (this.aspectRatio > 1) {
					drawWidth = drawWidth * this.aspectRatio;
					drawHeight = drawHeight * this.aspectRatio;
				}

				this.canvasWidth = drawWidth;
				this.canvasHeight = drawHeight;


				setTimeout(() => {
					this.drawImageHandler(true);
				}, 200);
			},
			chooseImage() {
				this.aspectRatio = 0;
				this.file = null;
				this.previewSrc = "";
				this.marginLeft = 0;
				this.marginTop = 0;
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'],
					sourceType: ['album', 'camera'],
					success: (res) => {
						this.file = res.tempFiles[0];
						// this.drawImageHandler();
						this.previewSrc = this.file.path;
						this.imgsListBg = this.file.path;

					}
				});
			},

			drawImageHandler(refresh = false) {
				let img = this.file;

				const minWidth = Math.min(img.width, img.height, 1500);
				this.aspectRatio = img.width / img.height;



				const ctx = uni.createCanvasContext('canvas1', this);

				let drawWidth = minWidth;
				let drawHeight = minWidth / this.aspectRatio;

				if (this.aspectRatio > 1) {
					drawWidth = drawWidth * this.aspectRatio;
					drawHeight = drawHeight * this.aspectRatio;
				}




				if (!refresh) {
					this.marginTop = 0;
					this.marginLeft = 0;
					this.cha = Math.abs(drawWidth - drawHeight);
					this.leftCha = 0;
					this.topCha = 0;
				}


				ctx.drawImage(
					img.path,
					this.leftCha,
					this.topCha,
					drawWidth,
					drawHeight
				);
				ctx.draw(true, () => {
					this.imageParts = [
						[],
						[],
						[],
						[],
						[],
						[],
						[],
						[],
						[]
					];
					const relaseStoreWidth = (this.storeWidth) / (300 + this.storeWidth * 2) * minWidth;

					for (let row = 0; row < 3; row++) {
						for (let col = 0; col < 3; col++) {




							let tempCanvas = {};
							tempCanvas.width = (minWidth - 2 * relaseStoreWidth) / 3;
							tempCanvas.height = (minWidth - 2 * relaseStoreWidth) / 3;


							uni.canvasToTempFilePath({
								canvasId: 'canvas1',
								x: col * tempCanvas.width + (relaseStoreWidth * col),
								y: row * tempCanvas.height + (relaseStoreWidth * row),
								width: tempCanvas.width,
								height: tempCanvas.height,
								success: (
									canvasData) => {
									this.$set(this.imageParts, [row * 3 + col], {
										data: canvasData.tempFilePath,
										filename: `${row * 3 + col + 1}-${new Date().getTime()}.png`
									});
									// console.log('this.imageParts', this.imageParts);

								},

							}, this)


						}

					};

				});






			},

			saveSingleImage(index) {
				// #ifndef H5
				return;
				// #endif
				if (index >= this.imageParts.length) return;

				const part = this.imageParts[index];

				// #ifdef H5
				const link = document.createElement('a');
				link.href = part.data;
				link.download = `图${index + 1}.png`;
				link.click();
				// #endif

				// #ifndef H5
				uni.downloadFile({
					url: part.data,
					success: (res) => {
						if (res.statusCode === 200) {
							uni.saveImageToPhotosAlbum({
								filePath: res.tempFilePath,
								success: () => {
									uni.showToast({
										title: '保存成功',
										icon: 'success'
									});
								},
								fail: () => {
									uni.showToast({
										title: '保存失败',
										icon: 'none'
									});
								}
							});
						}
					}
				});
				// #endif
			},

			saveAllImages() {
				if (this.imageParts.length === 0) {
					uni.showToast({
						title: '请先选择图片',
						icon: 'none'
					});
					return;
				}

				// #ifdef H5
				// const zip = new JSZip();
				// this.imageParts.forEach(part => {
				//   zip.file(part.filename, part.data.split("base64,")[1], { base64: true });
				// });

				// zip.generateAsync({ type: "blob" }).then(content => {
				//   saveAs(content, `九宫格图-${new Date().getTime()}.zip`);
				// });
				// #endif

				// #ifndef H5
				uni.showLoading({
					title: '保存中...',
					mask: true
				});

				// 小程序和App端逐个保存
				let savedCount = 0;
				const saveNext = (index) => {
					if (index >= this.imageParts.length) {
						uni.hideLoading();
						uni.showToast({
							title: `已保存${savedCount}张图片`,
							icon: 'success'
						});
						return;
					}

					const part = this.imageParts[index];
					uni.downloadFile({
						url: part.data,
						success: (res) => {
							if (res.statusCode === 200) {
								uni.saveImageToPhotosAlbum({
									filePath: res.tempFilePath,
									success: () => {
										savedCount++;
										saveNext(index + 1);
									},
									fail: () => {
										saveNext(index + 1);
									}
								});
							} else {
								saveNext(index + 1);
							}
						},
						fail: () => {
							saveNext(index + 1);
						}
					});
				};

				saveNext(0);
				// #endif
			},

			startMove(event) {
				this.lastTouchX = event.pageX || event.touches[0].pageX;
				this.lastTouchY = event.pageY || event.touches[0].pageY;
				this.isStartMove = true;
			},

			touchMove(event) {
				if (!this.isMobileDevice() && !this.isStartMove) {
					return;
				}

				event.preventDefault();

				if (this.lastTouchX === null) {
					this.lastTouchX = event.pageX || event.changedTouches[0].pageX;
					this.lastTouchY = event.pageY || event.changedTouches[0].pageY;
					return;
				}

				const currentX = event.pageX || event.changedTouches[0].pageX;
				const currentY = event.pageY || event.changedTouches[0].pageY;
				const x = currentX - this.lastTouchX;
				const y = currentY - this.lastTouchY;

				const width = Math.max(document.querySelector('.preview-box').clientWidth,
					document.querySelector('.preview-box').clientHeight);

				if (this.aspectRatio > 1) {
					this.marginLeft += x;
					if (Math.abs(this.marginLeft) > (width - 80) / 2) {
						this.marginLeft = Math.abs(this.marginLeft) / this.marginLeft * (width - 80) / 2;
					}
				} else {
					this.marginTop += y;
					if (Math.abs(this.marginTop) > (width - 80) / 2) {
						this.marginTop = Math.abs(this.marginTop) / this.marginTop * (width - 80) / 2;
					}
				}

				this.lastTouchX = currentX;
				this.lastTouchY = currentY;

				// 根据aspectRatio计算移动的距离
				if (this.aspectRatio > 1) {
					if (Math.abs(this.marginLeft) === 0) return;
					this.leftCha = Math.abs(this.marginLeft) / this.marginLeft * this.cha *
						(Math.abs(this.marginLeft) / ((width - 80))) * -1;
				} else {
					if (Math.abs(this.marginTop) === 0) return;
					this.topCha = Math.abs(this.marginTop) / this.marginTop * this.cha *
						(Math.abs(this.marginTop) / ((width - 80))) * -1;
				}
			},

			touchEnd() {
				this.lastTouchX = null;
				this.lastTouchY = null;
				this.isStartMove = false;
				this.drawImageHandler(true);
			},

			editWidth() {
				uni.showModal({
					title: '修改间隙',
					content: '请输入图片间隙',
					editable: true,
					placeholderText: this.storeWidth.toString(),
					success: (res) => {
						if (res.confirm) {
							let width = parseInt(res.content) || this.storeWidth;
							if (!(width >= 0)) {
								width = 4;
							}
							this.storeWidth = width;
							this.drawImageHandler(true);
						}
					}
				});
			},

			isMobileDevice() {
				const userAgent = navigator.userAgent || navigator.vendor || window.opera;
				return /android|iPad|iPhone|iPod|windows phone|mobile/i.test(userAgent);
			}
		}
	};
</script>

<style>
	page {
		background-color: #fff;
	}

	/* 公共样式 */


	.container {
		display: flex;
		flex-direction: column;
		align-items: center;


	}

	.imgs-list {
		display: flex;
		flex-wrap: wrap;
		width: 308px;
		height: 308px;

		position: relative;
		line-height: 0;
		cursor: pointer;
		border-radius: 8px;
	}

	.imgs-list-bg {
		position: absolute;
		z-index: -1;
		left: 0;
		top: 0;
		width: 100%;
		height: 100%;
		opacity: 0.8;
		filter: blur(16px);
		border-radius: 8px;
	}

	.imgs-list.loading {
		background-color: #f7f7f7;
		justify-content: center;
		align-items: center;
	}

	.placeholder-text {
		color: #666;
		font-size: 14px;
		text-align: center;
	}

	.imgs-list-item {
		width: 100px;
		height: 100px;
		margin-left: 4px;
		border-radius: 3px;
	}

	.imgs-list-item:nth-of-type(n+4) {
		margin-top: 4px;
	}

	.imgs-list-item:nth-of-type(3n+1) {
		margin-left: 0px;
	}

	.preview-box {
		position: relative;
		margin-top: 10px;
		overflow: hidden;
		border-radius: 4px;
		cursor: pointer;
		user-select: none;
		min-width: 80px;
		min-height: 80px;
		display: flex;
		justify-content: center;
		align-items: center;
		background-color: #f7f7f7;
	}

	.preview {
		opacity: 0.8;
		max-width: 100%;
		max-height: 100%;
	}

	.kuangkuang {
		width: 80px;
		height: 80px;
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		background-color: rgba(0, 0, 0, 0.5);
		border: 1px dashed #fff;
		border-radius: 4px;
		pointer-events: none;
	}

	.desc-text {
		color: #999;
		margin-top: 10px;
		font-size: 14px;
		text-align: center;
	}

	.edit-width {
		padding-left: 4px;
		color: #07c160;
	}

	.button-group {
		display: flex;
		justify-content: center;
		margin-top: 20px;
		width: 100%;
	}

	.choose-btn,
	.save-btn {
		background-color: #07c160;
		color: #fff;
		font-size: 14px;
		line-height: 40px;
		border-radius: 20px;
		height: 40px;
		padding: 0 20px;
		margin: 0 5px;
		border: none;
		outline: none;
	}

	.choose-btn {
		background-color: #f7f7f7;
		color: #666;
	}

	/* 响应式调整 */
	/* @media (max-width: 480px) {
		.imgs-list {
			width: calc(100vw - 40px);
			height: calc(100vw - 40px);
		}

		.imgs-list-item {
			width: calc((100vw - 40px - 2 * var(--store-width)) / 3);
			height: calc((100vw - 40px - 2 * var(--store-width)) / 3);
		}
	} */
</style>